package com.feinno.fpa;

import com.feinno.database.ConnectionString;
import com.feinno.database.DataRow;
import com.feinno.database.DataTable;
import com.feinno.database.Database;
import com.feinno.database.spi.DatabaseManager;
import com.feinno.superpojo.util.Outter;
import com.feinno.util.Outer;
import com.feinno.util.StringUtils;
import com.feinno.util.TypeUtils;
import org.helium.framework.spi.Bootstrap;
import com.feinno.util.TypeUtils;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Lei Gao on 8/12/15.
 */
public class FpaDictionary {
	Map<String, String> dict;
	public FpaDictionary() {//FOR TEST
		dict = new HashMap<>();
	}
	public FpaDictionary(Database db) throws SQLException {
		dict = new HashMap<>();
		db.executeTable("select word, chinese from FPA_Dict").getRows().forEach(
				row -> {
					try {
						String chinese = row.getString("chinese");
						if (chinese.length() > 0) {
							dict.put(row.getString("word").toLowerCase(), chinese);
						}
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
		);
		System.out.println("Dictionary Loaded:");
	}

	public String translate(String txt) {
		String result = "";
		for (String s: splitCamelWord(txt)) {
			String chinese = dict.get(s.toLowerCase());
			if (!StringUtils.isNullOrEmpty(chinese)) {
				result = result + chinese;
			} else {
				result = result + s;
			}
		}
		return result;
	}

	public static void main(String[] args) throws Exception {
		Bootstrap.INSTANCE.getClass();

		ConnectionString connStr = ConnectionString.fromText(FpaDatabase.connStrText);
		Database db = DatabaseManager.INSTANCE.getDatabase("FPA", connStr);

		DataTable table = db.executeTable("select * from entity");
		Map<String, String> dict = new HashMap<>();
		for (DataRow row: table.getRows()) {
			final String className = extractClassName(row.getString("className"));
			splitCamelWord(className).forEach(word -> putDic(dict, word, className));
			final String fieldName = row.getString("field");
			splitCamelWord(fieldName).forEach(word -> putDic(dict, word, fieldName));
		}
		DataTable table2 = db.executeTable("select * from function");
		for (DataRow row: table2.getRows()) {
			final String className = extractClassName(row.getString("className"));
			splitCamelWord(className).forEach(word -> putDic(dict, word, className));
			final String fieldName = row.getString("method");
			splitCamelWord(fieldName).forEach(word -> putDic(dict, word, fieldName));
		}
		DataTable table3 = db.executeTable("select * from ParameterDoc");
		for (DataRow row: table3.getRows()) {
			final String className = extractClassName(row.getString("parameter"));
			splitCamelWord(className).forEach(word -> putDic(dict, word, className));
		}
		String sql = "insert into FPA_Dict values (?, ?, \"\") on duplicate key update refs = ?";

		dict.forEach((k, v) -> {
			System.out.printf("word=%s, reference=%s\r\n", k, v);
			try {
				db.executeNonQuery(sql, k, v, v);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		});
	}

	public static String extractClassName(String className) {
		Outer<String> pack = new Outer<>();
		Outer<String> clazz = new Outer<>();
		StringUtils.splitWithLast(className, "/", pack, clazz);
		return clazz.value();
	}

	public static String extractPackageName(String className) {
		Outer<String> pack = new Outer<>();
		Outer<String> clazz = new Outer<>();
		StringUtils.splitWithLast(className, "/", pack, clazz);
		return pack.value().replace("/", ".");
	}

	public static void putDic(Map<String, String> dict, String word, String v2) {
		String v = dict.get(word);
		if (v == null) {
			dict.put(word, v2);
		} else {
			if (!v.contains(v2)) {
				String s = v.length() < 500 ? v + "," + v2 : v;
				dict.put(word, s);
			}
		}
	}

	public static List<String> splitCamelWord(String camelWord) {
		List<String> list = new ArrayList<>();
		if (camelWord == null) {
			return list;
		}
		String s = "";
		boolean hasLower = false;
		for (int i = 0; i < camelWord.length(); i++) {
			char c = camelWord.charAt(i);
			if (c == '/') {
				list.add(s.toLowerCase());
				hasLower = false;
				s = "";
				continue;
			}
			if (c >= 'A' && c <= 'Z' && hasLower) {
				list.add(s);
				s = "" + c;
				hasLower = false;
				continue;
			}
			if (c >= 'a' && c <= 'z') {
				hasLower = true;
			}
			s += c;
		}
		list.add(s);
		return list;
	}


	public static List<FpaParameter> parseParameters(String ss) {
		List<FpaParameter> result = new ArrayList<>();
		for (String s: TypeUtils.split(ss, ";")) {
			result.add(parseParameter(s));
		}
		return result;
	}

	public static FpaParameter parseParameter(String s) {
		FpaParameter p = new FpaParameter();
		p.type = s;
		return p;
	}

	public FpaExpand getExpand(String key) {
		return null;
	}
}
